	package com.darren.euc.interceptor;

import java.io.IOException;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.darren.euc.entity.AppSession;
import com.darren.euc.entity.LoginValidate;
import com.darren.euc.entity.User;
import com.darren.euc.service.LoginValidateService;
import com.darren.euc.service.UserService;
import com.darren.euc.util.JWTUtil;
import com.darren.euc.util.StringUtil;

import net.sf.json.JSONObject;


public class TokenInterceptor  implements HandlerInterceptor {
	
	private static final Log log = LogFactory.getLog(TokenInterceptor.class);	
	
	@Resource
	private LoginValidateService loginValidateService;
	
	@Autowired
    private UserService userService;
	private List<String> exceptUrls;

	public List<String> getExceptUrls() {
		return exceptUrls;
	}

	public void setExceptUrls(List<String> exceptUrls) {
		this.exceptUrls = exceptUrls;
	}
	public void afterCompletion(HttpServletRequest request,
			HttpServletResponse response, Object obj, Exception arg3)
			throws Exception {

	}

	public void postHandle(HttpServletRequest request, HttpServletResponse response,
			Object arg2, ModelAndView arg3) {		
		if(!StringUtil.isEmpty(arg3)){
			System.out.println("****************************************************************************************************");
			System.out.println("========= Redirect Path (Next View):========= "+ arg3.getViewName());
			System.out.println("****************************************************************************************************");
		}
		request.getAttribute("appSession");
		request.removeAttribute("appSession");
		request.removeAttribute("user");
	}

	public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object obj){
		String requestUri = request.getRequestURI();
		//放行exceptUrls中配置的url
		for (String url : exceptUrls) {
			if(url.endsWith("/**")){
				if (requestUri.startsWith(url.substring(0, url.length() - 3))) {
					return true;
				}
			} else if (requestUri.startsWith(url)) {
				return true;
			}
		}
		String accessToken = request.getHeader("accessToken");
		log.info(String.format("accessToken:%s;", accessToken));
		JSONObject responseJson = new JSONObject();
		if(JWTUtil.verifyAccessJWT(accessToken) == true){
			JSONObject playLoad = JWTUtil.getAccessPayload(accessToken);
			log.info(String.format("playLoad:%s", playLoad));
			Long exp = playLoad.getLong("exp");
			if(exp != null){//Token expiration validation
				java.util.Date myDate=new java.util.Date();					   
				if(exp < myDate.getTime()){
					//responseJson.put("status", -2);
					//responseJson.put("message", "accessToken已过期。");			
					//return ajax(responseJson.toString(),response);
				}
			}
			if(loginValidateService == null){
				log.info("loginValidateService is null");
			}
			LoginValidate loginValidate = loginValidateService.findById(Integer.parseInt(playLoad.getString("id")));
			
			if(loginValidate == null){//Login invalid, please login again.
				responseJson.put("status", -3);
				responseJson.put("message", "session失效，请重新登陆。");			
				return ajax(responseJson.toString(),response);
			}
			User user = userService.getUserById(loginValidate.getUserId());
			request.setAttribute("user", user);
			AppSession appSession = null;
			try {
				appSession = loginValidate.getApplicationSession();
			} catch (ClassNotFoundException | IOException ex) {
				log.error(ex.getMessage(),ex);
			}
			if(appSession == null){
				responseJson.put("status", -4);
				responseJson.put("message", "session失效，请重新登陆。");			
				return ajax(responseJson.toString(),response);
			}
			
			if(!StringUtil.isEmptyOrWhitespace(accessToken)){
				if(!accessToken.equals(appSession.getAttribute("accessToken"))){
					responseJson.put("status", -5);
					responseJson.put("message", "未找到对应的accessToken，请重新登陆。");			
					return ajax(responseJson.toString(),response);
				}
			}				
			response.setHeader("accessToken", accessToken);
			if(appSession != null){
				request.setAttribute("appSession", request);
			}
		}else{
			responseJson.put("status", -1);
			responseJson.put("message", "accessToken无效。");			
			return ajax(responseJson.toString(),response);
		}
		return true;
	}
	
	private boolean ajax(String content,HttpServletResponse response) {
		try {
			response.setContentType("text/html" + ";charset=UTF-8");		
			response.setHeader("Pragma", "No-cache");
			response.setHeader("Cache-Control", "no-cache");
			response.setDateHeader("Expires", 0);
			response.getWriter().write(content);
			response.getWriter().flush();
		} catch (IOException e) {
			log.error(e.getMessage(), e);
		}
		return false;
	}

}
